// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import m from 'mithril';
import {RecordingPageController} from '../../common/recordingV2/recording_page_controller';
import {
  EXTENSION_URL,
  RECORDING_MODAL_DIALOG_KEY,
} from '../../common/recordingV2/recording_utils';
import {
  CHROME_TARGET_FACTORY,
  ChromeTargetFactory,
} from '../../common/recordingV2/target_factories/chrome_target_factory';
import {targetFactoryRegistry} from '../../common/recordingV2/target_factory_registry';
import {WebsocketMenuController} from '../../common/recordingV2/websocket_menu_controller';
import {closeModal, showModal} from '../../widgets/modal';
import {CodeSnippet} from '../record_widgets';
import {RecordingMultipleChoice} from './recording_multiple_choice';

const RUN_WEBSOCKET_CMD =
  '# Get tracebox\n' +
  'curl -LO https://get.perfetto.dev/tracebox\n' +
  'chmod +x ./tracebox\n' +
  '# Option A - trace android devices\n' +
  'adb start-server\n' +
  '# Option B - trace the host OS\n' +
  './tracebox traced --background\n' +
  './tracebox traced_probes --background\n' +
  '# Start the websocket server\n' +
  './tracebox websocket_bridge\n';

export function showAddNewTargetModal(controller: RecordingPageController) {
  showModal({
    title: 'Add new recording target',
    key: RECORDING_MODAL_DIALOG_KEY,
    content: () =>
      m(
        '.record-modal',
        m('text', 'Select platform:'),
        assembleWebusbSection(controller),
        m('.line'),
        assembleWebsocketSection(controller),
        m('.line'),
        assembleChromeSection(controller),
      ),
  });
}

function assembleWebusbSection(
  recordingPageController: RecordingPageController,
): m.Vnode {
  return m(
    '.record-modal-section',
    m('.logo-wrapping', m('i.material-icons', 'usb')),
    m(
      '.record-modal-description',
      m('h3', 'Android device over WebUSB'),
      m(
        'text',
        'Android developers: this option cannot co-operate ' +
          'with the adb host on your machine. Only one entity between ' +
          'the browser and adb can control the USB endpoint. If adb is ' +
          'running, you will be prompted to re-assign the device to the ' +
          'browser. Use the websocket option below to use both ' +
          'simultaneously.',
      ),
      m(
        '.record-modal-button',
        {
          onclick: () => {
            closeModal(RECORDING_MODAL_DIALOG_KEY);
            recordingPageController.addAndroidDevice();
          },
        },
        'Connect new WebUSB driver',
      ),
    ),
  );
}

function assembleWebsocketSection(
  recordingPageController: RecordingPageController,
): m.Vnode {
  const websocketComponents = [];
  websocketComponents.push(
    m('h3', 'Android / Linux / MacOS device via Websocket'),
  );
  websocketComponents.push(
    m(
      'text',
      'This option assumes that the adb server is already ' +
        'running on your machine.',
    ),
    m(
      '.record-modal-command',
      m(CodeSnippet, {
        text: RUN_WEBSOCKET_CMD,
      }),
    ),
  );

  websocketComponents.push(
    m(
      '.record-modal-command',
      m('text', 'Websocket bridge address: '),
      m('input[type=text]', {
        value: websocketMenuController.getPath(),
        oninput() {
          websocketMenuController.setPath(this.value);
        },
      }),
      m(
        '.record-modal-logo-button',
        {
          onclick: () => websocketMenuController.onPathChange(),
        },
        m('i.material-icons', 'refresh'),
      ),
    ),
  );

  websocketComponents.push(
    m(RecordingMultipleChoice, {
      controller: recordingPageController,
      targetFactories: websocketMenuController.getTargetFactories(),
    }),
  );

  return m(
    '.record-modal-section',
    m('.logo-wrapping', m('i.material-icons', 'settings_ethernet')),
    m('.record-modal-description', ...websocketComponents),
  );
}

function assembleChromeSection(
  recordingPageController: RecordingPageController,
): m.Vnode | undefined {
  if (!targetFactoryRegistry.has(CHROME_TARGET_FACTORY)) {
    return undefined;
  }

  const chromeComponents = [];
  chromeComponents.push(m('h3', 'Chrome Browser instance or ChromeOS device'));

  const chromeFactory: ChromeTargetFactory = targetFactoryRegistry.get(
    CHROME_TARGET_FACTORY,
  ) as ChromeTargetFactory;

  if (!chromeFactory.isExtensionInstalled) {
    chromeComponents.push(
      m(
        'text',
        'Install the extension ',
        m('a', {href: EXTENSION_URL, target: '_blank'}, 'from this link '),
        'and refresh the page.',
      ),
    );
  } else {
    chromeComponents.push(
      m(RecordingMultipleChoice, {
        controller: recordingPageController,
        targetFactories: [chromeFactory],
      }),
    );
  }

  return m(
    '.record-modal-section',
    m('.logo-wrapping', m('i.material-icons', 'web')),
    m('.record-modal-description', ...chromeComponents),
  );
}

const websocketMenuController = new WebsocketMenuController();
